import { Clock, registerOnTick } from '$lib/clock';
import { Types, defineComponent, defineQuery, hasComponent, type Component, type Entity, type IWorld } from '$lib/ecs';

/**
 * Heart is essentially creature's inner clock. All time-consuming action
 * durations and over time effects should scale proportional to heartbeat duration.
 */
export const Heart = defineComponent('Heart', {
  heartbeat: Types.ui16,
  elapsed: Types.ui16,
});

export const heartQuery = defineQuery([Heart])

const onHeartbeat: [Component, any][] = [];

export const registerOnHeartBeat = (component: Component, system) => {
  onHeartbeat.push([component, system]);
};

export const processHeatBeat = (world) => {
  for (let e of heartQuery(world)) {
    const elapsed = Heart.elapsed[e]+1;
    if (elapsed >= Heart.heartbeat[e]) {
      Heart.elapsed[e] = 0;
      for (let [component, system] of onHeartbeat) {
        if (hasComponent(world, component, e)) {
          system(world, e);
        }
      }
    } else {
      Heart.elapsed[e] = elapsed;
    }
  }
};

export const withHeartBeats = (n: number, e, action) => {
  // TODO
  return () => {
    const delay = n * Heart.heartbeat[e];
    Clock.time[e] += delay;
    action();
  };
};

export const applyHeartDelay = (world: IWorld, e: Entity, n: number) => {
  const delay = n * Heart.heartbeat[e];
  Clock.time[e] += delay;
};

registerOnTick(processHeatBeat);
